<template>
  <div>
    <div v-if="realMode===false">
      <div v-if="learning===false">
        <p class="pText" :style="{opacity: isBoss ? 0.5 : 1 }">选择开局分类：</p>
        <el-select v-model="selectOpen" placeholder="请选择" size="mini" class="firstLine" @change="changeOpeningSort" clearable :style="{opacity: isBoss ? 0.5 : 1 }">
          <el-option
              v-for="item in openOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value">
          </el-option>
        </el-select>
        <p class="pText" :style="{opacity: isBoss ? 0.5 : 1 }">直接筛选：</p>
        <el-select v-model="openingName" placeholder="请选择一个开局" size="mini" @change="changeOpening" class="firstLine" :style="{opacity: isBoss ? 0.5 : 1 }">
          <el-option
              v-for="item in openingList"
              :key="item.value"
              :label="item.label"
              :value="item.value">
          </el-option>
        </el-select>
        <el-tooltip class="item" effect="dark" content="学习开局的时候可设置星标开局，此处仅筛选星标开局" placement="top">
         <el-checkbox v-model="selectStar" @change="searchOpening" style="margin-left: 5px;margin-right: 5px">仅看星标</el-checkbox>
        </el-tooltip>
        <el-button class="firstLine" @click="updateManagerStatus" :type="isManager ? 'info' : 'primary'"  :style="{opacity: isBoss ? 0.5 : 1 }" size="mini">{{isManager === true ? '返回' : '新增'}}</el-button>
        <el-button class="firstLine" @click="enterRealMode" type="success" size="mini" :style="{opacity: isBoss ? 0.5 : 1 }">实战模式</el-button>
        <el-button class="firstLine" @click="importModal=true" type="warning" size="mini" :style="{opacity: isBoss ? 0.5 : 1 }">导入开局</el-button>
        <!--管理端-->
        <div v-if="isManager">
          <p  class="firstLine" :style="{opacity: isBoss ? 0.025 : 1 }">开局名: </p> <el-input   class="firstLine" style="width: 300px" v-model="manageName" size="mini"></el-input>
          <p  class="firstLine" :style="{opacity: isBoss ? 0.025 : 1 }">变例名: </p> <el-input  class="firstLine"  style="width: 300px" v-model="manageSubName" size="mini"></el-input>
          <el-button type="success" size="mini" @click="saveManageOpening" :style="{opacity: isBoss ? 0.25 : 1 }">保存</el-button>
          <el-button type="warning" size="mini" @click="getFen" :style="{opacity: isBoss ? 0.25 : 1 }">fen</el-button>
          <el-button type="danger" size="mini" @click="initEditName" :style="{opacity: isBoss ? 0.25 : 1 }">编辑</el-button>
          <el-button type="info" size="mini" @click="clearManage" :style="{opacity: isBoss ? 0.25 : 1 }">清空</el-button>
          <el-button type="primary" icon="el-icon-refresh" class="f-m-5" size="small" round @click="reverseBoard" :style="{opacity: isBoss ? 0.25 : 1 }"></el-button>
          <el-tooltip class="item" effect="dark" content="导入Fgn局面" placement="top">
            <el-button type="info" icon="el-icon-edit" class="f-m-5" size="small" round @click="parseFgnModal=true" :style="{opacity: isBoss ? 0.25 : 1 }"></el-button>
          </el-tooltip>
          <el-row>
            <el-col :span=12>
              <p class="firstLine" :style="{opacity: isBoss ? 0.5 : 1 }">当前开局名: {{currentOpeningName}}</p>
            </el-col>
            <el-col :span=9>
              <el-button type="warning" round  class="firstLine" size="small"  @click="isBoss=!isBoss" :style="{opacity: isBoss ? 0.25 : 1 }">老板键</el-button>
              <el-button type="warning" round  class="firstLine" size="small"  @click="undoManage" :style="{opacity: isBoss ? 0.25 : 1 }">撤回</el-button>
              <el-button type="danger" round  class="firstLine" size="small" :loading=analyzeLoading @click="analyzeCurrentFen" :style="{opacity: isBoss ? 0.25 : 1 }">分析</el-button>
              <p class="firstLine" :style="{opacity: isBoss ? 0.5 : 1 }">当前评分: {{currentOpeningValue}}</p>
            </el-col>
            <el-col :span=3>
              <p class="firstLine" :style="{opacity: isBoss ? 0.5 : 1 }">下一步: {{bestNextMove}}</p>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span=7>
              <chessboard :onPromotion="promote" :orientation="boardColor" @onMove="getManageBoardInfo" :fen="currentFen"
                          :style="{opacity: isBoss ? 0.025 : 1 }"/>
            </el-col>
            <el-col :span=17>
              <el-table :data="manageData" border stripe  style="width: 100%" height="300px" :style="{opacity: isBoss ? 0.5 : 1 }"  >
                <el-table-column
                    type="index"
                    label="序号"
                    width="50">
                </el-table-column>
                <el-table-column
                    prop="move"
                    label="走法"
                    width="100"
                >
                </el-table-column>
                <el-table-column :show-overflow-tooltip="true"
                    prop="description"
                    label="解读"
                >
                </el-table-column>
                <el-table-column
                    fixed="right"
                    width="150"
                    label="操作"
                >
                  <template slot-scope="scope">
                    <el-button type="success" size="mini" @click="editManageData(scope.$index)">编辑</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span=12>

              <h5 :style="{opacity: isBoss ? 0.5 : 1 }">大数据:
                <span style="margin-left: 320px"> 总步数: {{manageData.length}} </span>
              </h5>
              <el-table :data="bigData" stripe :height="200" class="f-m-5" v-loading="bigDataLoading" element-loading-text="拼命加载中" :style="{opacity: isBoss ? 0.5 : 1 }">
                <el-table-column
                    prop="move"
                    label="走法"
                    width="70">
                </el-table-column>
                <el-table-column
                    prop="result"
                    label="白/平/黑"
                >
                </el-table-column>
                <el-table-column
                    fixed="right"
                    width="150"
                    label="操作"
                >
                  <template slot-scope="scope">
                    <el-button type="success" size="mini" @click="chooseStep(scope.$index)" :style="{opacity: isBoss ? 0.25 : 1 }">选择</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>
            <el-col :span=12>
              <h5 :style="{opacity: isBoss ? 0.025 : 1 }">名局: </h5>
              <el-table :data="topGames" stripe border  :height="200" class="f-m-5" v-loading="bigDataLoading" element-loading-text="拼命加载中" :style="{opacity: isBoss ? 0.5 : 1 }">
                <el-table-column
                    prop="white"
                    label="白方"
                    width="150">
                </el-table-column>
                <el-table-column
                    prop="black"
                    label="黑方"
                    width="150">
                </el-table-column>
                <el-table-column
                    prop="result"
                    label="结果"
                >
                </el-table-column>
                <el-table-column
                    prop="date"
                    label="年月"
                >
                </el-table-column>
              </el-table>
            </el-col>
          </el-row>
          <el-dialog
              :visible.sync="editManageModal"
              title="增加描述"
              width="800px"
              :close-on-click-modal="false"
              :close-on-press-escape="false"
          >
            <p class="f-m-5">描述: </p> <el-input class="f-m-5" type="textarea" :autosize="{ minRows: 5}"  v-model="description"></el-input>
            <el-button @click="editManageModal = false" size="mini">取消</el-button>
            <el-button type="primary" @click="updateSingleManageData" size="mini" >确定</el-button>
          </el-dialog>
          <!--开局名修改-->
          <el-dialog
              :visible.sync="editNameModal"
              title="修改开局名"
              width="800px"
              :close-on-click-modal="false"
              :close-on-press-escape="false"
          >
            <p>新的开局名:
              <el-input v-model="newName" style="width: 700px"></el-input>
            </p>
            <p>新的变例名:
              <el-input v-model="newSubName" style="width: 700px"></el-input>
            </p>
            <el-button @click="editNameModal = false">取消</el-button>
            <el-button type="primary" @click="editOpeningName">确定</el-button>
          </el-dialog>
          <el-dialog
              :visible.sync="parseFgnModal"
              title="导入fgn"
              width="800px"
              :close-on-click-modal="false"
              :close-on-press-escape="false"
          >
            <p>fgn:
              <el-input v-model="fgn" style="width: 700px"></el-input>
            </p>
            <el-button @click="parseFgnModal = false">取消</el-button>
            <el-button type="primary" @click="parseFgn">确定</el-button>
          </el-dialog>
        </div>
        <!--用户端-->
        <div v-if="!isManager">
          <el-table :data="openingData" border stripe :height="640" :style="{opacity: isBoss ? 0.2 : 1 }">
            <el-table-column
                type="index"
                label="序号"
                width="80">
            </el-table-column>
            <el-table-column :show-overflow-tooltip="true"
                prop="name"
                label="开局名"
                width="180"
            >
            </el-table-column>
            <el-table-column :show-overflow-tooltip="true"
                prop="subName"
                label="变例"
            >
            </el-table-column>
            <el-table-column
                prop="moveCount"
                label="步数"
                width="80"
            >
            </el-table-column>
            <el-table-column
                prop="descriptionCount"
                label="解析数"
                width="80"
            >
            </el-table-column>
            <el-table-column
                fixed="right"
                label="操作"
                width="250"
            >
              <template slot-scope="scope">
                <el-button @click="learn(scope.row)" type="primary" size="mini">学习</el-button>
                <el-button type="warning" size="mini" @click="editOpening(scope.row)">编辑</el-button>
                <el-button type="danger" size="mini" @click="exportOpening(scope.row)">导出</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <div v-if="learning===true">
        <p  class="firstLine" :style="{opacity: isBoss ? 0.025 : 1 }">开局名: </p> <el-input   class="firstLine" style="width: 250px" v-model="currentOpening.name" readonly size="mini"></el-input>
        <p  class="firstLine" :style="{opacity: isBoss ? 0.025 : 1 }">变例名: </p> <el-input  class="firstLine"  style="width: 450px" v-model="currentOpening.subName"  readonly size="mini"></el-input>
        <el-button @click="recite" size="mini" class="firstLine" :type="isRecite ? 'primary' : 'info'" :style="{opacity: isBoss ? 0.1 : 1 }">{{ reciteText }}</el-button>
        <el-button type="warning" size="mini" @click="getUserFen" :style="{opacity: isBoss ? 0.1 : 1 }">提取Fen</el-button>
        <el-button type="warning" size="mini" @click="exportCurrentPgn" :style="{opacity: isBoss ? 0.1 : 1 }">导出棋谱</el-button>
        <el-button type="info" size="mini" @click="exportSimplePgn" :style="{opacity: isBoss ? 0.1 : 1 }">简谱</el-button>
        <el-row>
          <el-col :span=7>
            <div  >
              <chessboard  id="capture" :onPromotion="promote" :free="ifFree" :orientation="boardColor" @onMove="getInfo"
                           :fen="openingFen" :style="{opacity: isBoss ? 0.025 : 1 }"/>
            </div>
          </el-col>
          <el-col :span=17 v-if="!isRecite">
            <el-table :data="openingMoveHistory" border stripe
                      highlight-current-row :height="250"
                      @cell-click="handleSelectMove" :style="{opacity: isBoss ? 0.3 : 1 }" >
              <el-table-column
                  type="index"
                  label="步数"
                  width="50">
              </el-table-column>
              <el-table-column
                  prop="white"
                  label="白方"
              >
              </el-table-column>
              <el-table-column
                  prop="black"
                  label="黑方"
              >
              </el-table-column>
            </el-table>
            <el-row>
              <el-tooltip class="item" effect="dark" content="翻转黑白朝向" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="info" icon="el-icon-refresh" class="f-m-5" size="small" @click="reverseBoard"></el-button>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="回到最开始" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="primary"  round icon="el-icon-d-arrow-left" class="f-m-5" size="small" @click="jumpToBegin" :loading=autoLoading ></el-button>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="后退一步" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="primary" round icon="el-icon-arrow-left" class="f-m-5" size="small"  @click="jumpToBack" :loading=autoLoading></el-button>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="前进一步" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="primary" round icon="el-icon-arrow-right" class="f-m-5" size="small" @click="jumpToNext" :loading=autoLoading></el-button>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="跳转到末尾" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="primary" round icon="el-icon-d-arrow-right" class="f-m-5" size="small" @click="jumpToEnd" :loading=autoLoading></el-button>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="自动播放" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="warning" round icon="el-icon-caret-right" class="f-m-5" size="small" :loading=autoLoading @click="autoMove"></el-button>
              </el-tooltip>

              <el-tooltip class="item" effect="dark" content="设置或取消星标，在筛选页面可以单独筛选星标开局" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="success" round :icon="star==1 ? 'el-icon-star-on' : 'el-icon-star-off'" class="f-m-5" size="small" :loading=autoLoading @click="starOpening"></el-button>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="当前局面转图片导出（一般只有作者本人才会用到）" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1}" type="warning" round icon="el-icon-scissors" class="f-m-5" size="small" :loading=autoLoading @click="screenCut"></el-button>
              </el-tooltip>
              <el-button type="danger" round icon="el-icon-circle-close" class="f-m-5" size="small" :loading=autoLoading  @click="learning=false;isRecite=false;" :style="{opacity: isBoss ? 0.1 : 1 }"></el-button>
              <el-tooltip class="item" effect="dark" content="老板键" placement="top">
                <el-button :style="{opacity: isBoss ? 0.1 : 1 }"  type="danger" round icon="el-icon-s-platform" class="f-m-5" size="small" style="margin-left: 300px" :loading=autoLoading @click="isBoss=!isBoss"></el-button>
              </el-tooltip>
            </el-row>
          </el-col>
        </el-row>
        <div v-if="!isRecite">
          <h4>解读:</h4>
          <el-input class="textarea" type="textarea" :autosize="{ minRows: 6}" readonly v-model="currentDescription" ></el-input>
        </div>
      </div>
    </div>
    <div v-if="realMode===true" >
      <el-row>
        <el-col :span=7>
          <div>
            <chessboard  :onPromotion="promote" :orientation="realModeColor" @onMove="getRealModeBoardInfo" :fen="realModeFen"
                         :style="{opacity: isBoss ? 0.05 : 1 }"/>
          </div>
          <el-tooltip class="item" effect="dark" content="翻转黑白朝向" placement="top">
            <el-button :disabled="!isBeginRealMode" :style="{opacity: isBoss ? 0.1 : 1 }"  type="info" icon="el-icon-refresh" class="f-m-5" size="small" @click="reverseRealModeBoard"></el-button>
          </el-tooltip>
        </el-col>
        <el-col :span="14">
          <p>先选择先后手，然后点击开始进入实战模式</p>
          <p>系统会在 {{openingName}} 的所有变例随机抽取</p>
          <p>请选择:
            <el-radio v-model="realModeSide" label="white" @input="sideSelect" :disabled="isBeginRealMode">白方</el-radio>
            <el-radio v-model="realModeSide" label="black" @input="sideSelect" :disabled="isBeginRealMode">黑方</el-radio>
          </p>
          <div class="firstLine">
            <el-button @click="startRealMode" size="mini" type="info" :disabled="isBeginRealMode">开始</el-button>
            <el-button @click="resetRealMode" size="mini" type="warning" :disabled="!isBeginRealMode">重置</el-button>
            <el-button @click="quitRealMode" size="mini" type="danger">退出</el-button>
          </div>

        </el-col>
      </el-row>

      <el-dialog
          :visible.sync="endGameModal"
          title="选择对应的开局"
          width="800px"
          :close-on-click-modal="false"
          :close-on-press-escape="false"
      >
        <p>开局:
          <el-select v-model="endGameSelect" placeholder="请选择一个开局" size="mini"  class="firstLine" :style="{opacity: isBoss ? 0.5 : 1 }">
            <el-option
                v-for="item in endGameSelectData"
                :key="item.value"
                :label="item.label"
                :value="item.value">
            </el-option>
          </el-select>
        </p>
        <el-button @click="endGameModal = false">取消</el-button>
        <el-button type="primary" @click="sendEndGameCheck">确定</el-button>
      </el-dialog>
    </div>
    <el-dialog
        :visible.sync="importModal"
        title="导入开局"
        width="800px"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
    >
      <p>选择Json文件:   <input type="file" @change="handleImportFile" > {{importFilePath}} </p>

      <el-button @click="importModal = false" size="mini">取消</el-button>
      <el-button type="primary" @click="importOpening" size="mini">确定</el-button>
    </el-dialog>
  </div>
</template>

<script>

import {checkIllegalText, invoke, parseFenDropHistory, randomFromArray, sleep} from "@/lib/utils";
import * as utils from "@/lib/utils";
import {beginGif, DEFAULT_CONFIG} from "@/lib/constants";
import path from "path";
import Sqlite from "@/lib/sqlite";
import Chessmate from "@/lib/chessmate";
import {chessboard} from "vue-chessboard";
import Database from "@/lib/database";
import {clipboard} from "electron";
import {getBigData} from "@/lib/reptile";
import _ from "lodash";
import chessmate from "@/lib/chessmate";
import {exportOpeningData} from "@/lib/file";
import fs from "fs";
import domtoimage from 'dom-to-image-more';
import {left} from "core-js/internals/array-reduce";
import emitvue from "@/lib/emitvue";

export default {
  name: "Opening",
  data() {
    return {
      isDev: false,
      appPath: null,
      isManager: false,
      boardColor: 'white',
      currentFen: utils.newGame,
      ifFree: false,

      // 开局分类
      openingList: [],
      openingName: '',
      openingData: [],

      // 管理端
      manageName: null,
      manageSubName: null,
      manageData: [], // move,description,children
      editManageModal: false,
      description: '',
      editIndex: 0,
      currentOpeningName: '', // 当前管理端的开局名
      editNameModal: false,
      newName: '',
      newSubName: '',
      isBoss: false, // 老板键
      parseFgnModal: false, // 解析fgn并且自动转为棋步的功能
      fgn: '',
      // 记录每一步的fen
      manageFenHistory: [],

      // 用户端
      learning: false,
      currentOpening: null,
      openingFen: '',
      moveNum: 0,
      // 历史记录，分黑白棋
      openingMoveHistory: [],
      // 不分黑白棋的记录
      moveList: [],
      tempFen: null, // 用来记录当前棋步和下一步是否是棋谱里的
      // 当前的解读
      currentDescription: '',
      autoLoading: false,
      bigDataLoading: false,
      bigData: [],
      topGames: [],
      // 用户端 背谱模式
      isRecite: false,
      reciteText: '背谱模式',
      // select查询
      openOptions: [
        {value: 'A', label: 'A类 不规则开局'},
        {value: 'B', label: 'B类 半开放性布局'},
        {value: 'C', label: 'C类 开放性布局'},
        {value: 'D', label: 'D类 以1.d4 d5开局的后翼弃兵开局'},
        {value: 'E', label: 'E类 1.d4 Nf6 2. c4 e6或者g6开局的封闭性布局'},
      ],
      selectOpen: null,
      currentOpeningValue: '',
      bestNextMove: '',
      analyzeLoading: false,

      // 实战模式变量
      realMode: false,
      realModeData: {},
      realModeEndGameMap: {},
      realModeFen: utils.emptyGame,
      // 实战模式棋盘朝向 支持切换
      realModeColor: 'white',
      // 实战模式选的边，这个是不能切换的
      realModeSide: 'white',
      exportFilePath: './',
      pluginPath: '',
      realModeLastFen: utils.newGame, // 用于实战模式下错返回
      isBeginRealMode: false, // 目前是否是开始状态
      reverseJump: false, // 因为切换角度而导致的棋盘颜色切换
      endGameModal: false, // 是否展开结尾的对话框
      endGameSelect: '', // 结尾的选择
      endGameSelectData: [], // 开局的选择框

      // 导入开局
      importModal: false,
      importFilePath: '',
      star: 0, // 某开局是否为星标
      selectStar: false,
    }
  },
  methods: {
    left,
    updateManagerStatus() {
      this.isManager = !this.isManager
    },
    async getSetting() {
      this.appPath = await invoke('getCurrentPath', null)
      let config = await invoke('get', {name: 'setting', type: 'database'})
      this.pluginPath = config.pluginPath

      if (!config) {
        await invoke('set', JSON.stringify({name: 'setting', type: 'database', dbPath: '', enginePath: ''}))
      } else {
        await Sqlite.connectTutorial(config.tutorialDbPath)
        const chessConfig = {
          path: config.enginePath,
          analyzeSpeed: config.analyzeSpeed,
          blunderThreshold: config.blunderThreshold,
          mistakeThreshold: config.mistakeThreshold,
        }
        this.exportFilePath = config.exportFilePath || './'
        await Chessmate.init(chessConfig)
      }
    },
    // 升变
    promote() {
      if (confirm("是否升变为后？")) {
        return 'q'
      } else {
        if (confirm("是否升变为车？")) {
          return 'r'
        } else {
          if (confirm("是否升变为马？")) {
            return 'n'
          } else {
            if (confirm("是否升变为象？")) {
              return 'b'
            }
          }
        }
      }
      return 'q'
    },
    // 编辑模式的获取
    async getManageBoardInfo(data) {
      if (data.history.length === 0) return
      this.manageData.push({move: data.history[data.history.length - 1], description: ''})
      this.currentFen = data.fen
      this.bigDataLoading = true
      await this.getInfoFromLichess(this.currentFen)
      this.manageFenHistory.push(this.currentFen)
    },
    // 选择这步棋
    async chooseStep(index) {
      const move = this.bigData[index]?.move
      this.currentFen = Chessmate.move(this.currentFen, move)
      this.manageFenHistory.push(this.currentFen)
      this.manageData.push({move, description: ''})
      this.bigDataLoading = true
      await this.getInfoFromLichess(this.currentFen)
      this.bigDataLoading = false
    },
    async analyzeCurrentFen() {
      this.analyzeLoading = true
      const res = await Chessmate.analyzeCurrentFenValue(this.currentFen)
      this.currentOpeningValue = res.valueText
      this.bestNextMove = res.move
      this.analyzeLoading = false
    },
    editManageData(index) {
      this.editManageModal = true
      this.editIndex = index
      this.description = this.manageData[this.editIndex].description
    },
    async getInfoFromLichess (fen) {
      const {bigData, topGames, nameEn } = await getBigData(fen)
      this.bigDataLoading = false
      this.bigData = bigData
      this.topGames = topGames
      if (nameEn !== "") {
        this.currentOpeningName = nameEn
      }
    },
    // 撤回编辑的上一步
    async undoManage() {
      if (this.manageFenHistory.length === 0) return this.$notify({duration: 1000, title: '通知', message: `已经到开头了`, type: 'warning'})
      this.manageFenHistory.pop()
      this.currentFen = this.manageFenHistory[this.manageFenHistory.length - 1] || utils.newGame
      this.manageData.pop()
      this.bigDataLoading = true
      await this.getInfoFromLichess(this.currentFen)
    },
    updateSingleManageData() {
      if (checkIllegalText(this.description)) {
        return this.$notify({duration: 1000, title: '通知', message: `描述不允许为空或包含特殊符号`, type: 'warning'})
      }
      this.manageData[this.editIndex].description = this.description
      this.editIndex = 0
      this.editManageModal = false
      this.description = ''
    },
    // 把Fen复制出来
    getFen() {
      let fen = this.currentFen
      fen = parseFenDropHistory(fen)
      this.$notify({duration: 1000, title: '通知', message: `${fen} 已经复制到剪切板`, type: 'success'})
      clipboard.writeText(fen)
    },
    getUserFen() {
      let fen = this.openingFen
      fen = parseFenDropHistory(fen)
      this.$notify({duration: 1000, title: '通知', message: `${fen} 已经复制到剪切板`, type: 'success'})
      clipboard.writeText(fen)
    },
    // 当前棋谱提取为fgn
    exportCurrentPgn() {
      // 去掉第一位
      const moveList = []
      for (let i=1; i<this.moveList.length; i++) {
        moveList.push(this.moveList[i])
      }
      const pgn = chessmate.exportPgn2Pdf(moveList, this.currentOpening.name, this.currentOpening.subName,
          this.exportFilePath, this.pluginPath)
      clipboard.writeText(pgn)
      // 打开文件选择对话框
      this.$notify({duration: 1000, title: '通知', message: "棋谱数据已经复制到剪切板并导出成文件", type: 'success'})
    },
    // 清空管理端的局面
    clearManage() {
      this.$notify({duration: 1000, title: '通知', message: "处理完成", type: 'success'})
      this.currentFen = utils.newGame
      this.manageSubName = ''
      // 开局名不清理 因为一般都是同一个开局
      this.manageData = []
      this.currentOpeningName = ''
      this.manageFenHistory = []
    },
    // 保存开局
    async saveManageOpening() {
      if (!this.manageName || !this.manageSubName || (this.manageData.length === 0)) {
        return this.$notify({duration: 1000, title: '通知', message: "开局信息缺失，无法保存", type: 'warning'})
      }
      if (checkIllegalText(this.manageName) || checkIllegalText(this.manageSubName)) {
        return this.$notify({duration: 1000, title: '通知', message: "开局名称不允许特殊字符", type: 'warning'})
      }
      for (let i=0;i<this.manageData.length;i++) {
        this.manageData[i] = {move: this.manageData[i].move, description: this.manageData[i].description}
      }
      await Database.updateOpening(this.manageName, this.manageSubName, JSON.stringify(this.manageData))
      // 刷新编辑状态
      this.isManager = false
      await this.changeOpening(this.openingName)
      await this.clearManage()
      await this.getOpeningSort()
    },
    // 解析fgn并且应用到棋盘，便于快速布阵
    async parseFgn() {
      const list = this.fgn.split('.')
      this.fgn = ''
      this.currentFen = utils.newGame
      this.manageFenHistory = []
      this.manageData = []
      for (const item of list) {
        // 跳过开头的对局名文字
        if (item[0] === 'A' || item[0] === 'B' || item[0] === 'C' || item[0] === 'D' || item[0] === 'E') {
          // 注意不要过滤类似于Be3这样的棋步
          if (!_.isNaN(Number(item[1]))) continue
        }
        const moveList = item.split(' ')
        for (const move of moveList) {
          if (!_.isNaN(parseFloat(move))) continue
          try {
            this.currentFen = Chessmate.move(this.currentFen, move)
            this.manageFenHistory.push(this.currentFen)
            this.manageData.push({move, description: ''})
            this.bigDataLoading = true
            await this.getInfoFromLichess(this.currentFen)
            this.bigDataLoading = false
          } catch {
            console.log("move ", move, '非法')
          }
        }
      }
      this.parseFgnModal = false
    },
    async editOpeningName() {
      await Database.editOpeningName(this.manageName, this.manageSubName, this.newName, this.newSubName)
      this.$notify({duration: 1000, title: '通知', message: `编辑成功`, type: 'success'})
      this.editNameModal = false
      this.isManager = false
      await this.changeOpening(this.newName)
    },
    // 处理点击编辑后的数据初始化
    initEditName() {
      this.editNameModal = true
      this.newName = this.manageName
      this.newSubName = this.manageSubName
    },
    // 选择一个开局
    async changeOpening(val) {
      this.openingName = val
      await this.searchOpening()
    },
    async searchOpening() {
      let star = null
      if (this.selectStar === true) star =1
      const res = await Database.getOpening(this.openingName, star)
      for (const item of res) {
        item.data = utils.decrypt(item.data)
        item.data = JSON.parse(item.data)
        let moveCount = item.data?.length
        let descriptionCount = 0
        for (const info of item.data) {
          if (info.description) descriptionCount++
        }
        item.moveCount = moveCount
        item.descriptionCount = descriptionCount
      }
      this.openingData = res
    },
    async changeOpeningSort(val) {
      this.openingList = []
      const group = await Database.getOpeningGroup(val)
      for (const item of group) {
        this.openingList.push({label: item.name, value: item.name})
      }
      this.openingName = ''
    },
    async learn(data) {
      this.learning = true
      this.currentOpening = data
      this.moveList = data.data
      this.openingFen = utils.newGame
      this.moveNum = 0
      this.parseMove2History()
      this.parseMoveList()
      this.star = data.star
    },
    async editOpening(data) {
      this.manageName = data.name
      this.manageSubName = data.subName
      this.manageData = data.data
      this.isManager = true
      let initFen = utils.newGame
      for (const item of this.manageData) {
        initFen = Chessmate.move(initFen, item.move)
        this.manageFenHistory.push(initFen)
      }
      this.currentFen = initFen
      await this.getInfoFromLichess(this.currentFen)
    },
    // 导出开局
    async exportOpening(data) {
      console.log("data", data)
      exportOpeningData(this.exportFilePath, data)
      this.$notify({duration: 1000, title: '通知', message: `导出成功`, type: 'success'})
    },
    parseMoveList() {
      // 开局默认有一个初始局面的历史记录，避免按钮不好处理
      let currentFen = utils.newGame
      const res = [{fen: currentFen, description: ''}]
      for (const item of this.moveList) {
        const fen = Chessmate.move(currentFen, item.move)
        item.fen = fen
        res.push(item)
        currentFen = fen
      }
      this.moveList = res

    },
    // 记谱模式
    recite() {
      if (this.isRecite === false) {
        this.isRecite = true
        this.reciteText = '退出背谱'
        if (!this.moveList[this.moveNum+1]) {
          this.$notify({duration: 1000, title: '通知', message: `已到棋局末尾，从初始状态开始背谱`, type: 'warning'})
          this.jumpToBegin()
        } else {
          this.$notify({duration: 1000, title: '通知', message: `请自行移动棋子开始背谱，在棋步末尾会自动退出本模式`, type: 'success'})
        }
      } else {
        this.isRecite = false
        this.reciteText = '背谱模式'
        this.$notify({duration: 1000, title: '通知', message: "退出背谱模式", type: 'success'})
      }
    },
    // 走棋触发
    async getInfo(data) {
      // 手动更新双向绑定的值，否则不会被改动
      this.openingFen = parseFenDropHistory(data.fen)
      // 有历史记录说明是用户手动下的棋，在这个模块里不支持手动下棋谱外的棋
      if (data.history?.length) {
        if (this.moveList[this.moveNum+1].fen !== this.openingFen) {
          this.$notify({duration: 1000, title: '通知', message: "该落子不是正确的落子", type: 'warning'})
          await utils.sleep(200)
          this.openingFen = this.moveList[this.moveNum].fen
          return
        } else {
          this.moveNum++
        }
      }
      if (!this.moveList[this.moveNum+1]) {
        if (this.isRecite === true) {
          this.$notify({duration: 1000, title: '通知', message: "退出背谱模式", type: 'success'})
          this.isRecite = false
          this.reciteText = '背谱模式'
        }
      }
      // 人为走子也应该读取解析
      this.currentDescription = this.moveList[this.moveNum]?.description || ''
    },
    // TODO 支持选择某一列然后跳转棋谱
    handleSelectMove(row, column, cell, event) {
      console.log("column",column);
      console.log("row",row);
    },
    // 几个跳转的按钮
    jumpToBegin() {
      this.moveNum = 0
      this.openingFen = this.moveList[this.moveNum].fen
      this.currentDescription = this.moveList[this.moveNum].description
    },
    jumpToBack() {
      this.moveNum--
      console.log("jumpToBack this.moveNum", this.moveNum)
      if (this.moveNum < 0 ) {
        this.jumpToBegin()
      }
      else {
        this.openingFen = this.moveList[this.moveNum].fen
        this.currentDescription = this.moveList[this.moveNum].description
      }
    },
    jumpToNext() {
      this.moveNum++
      if (this.moveNum > this.moveList.length) {
        // 没必要做任何操作
        this.$notify({duration: 1000, title: '通知', message: "已经来到了棋局末尾", type: 'success'})
        this.moveNum--
      }
      else {
        this.openingFen = this.moveList[this.moveNum].fen
        this.currentDescription = this.moveList[this.moveNum].description
      }
    },
    jumpToEnd() {
      if (this.moveList.length) {
        this.openingFen = this.moveList[this.moveList.length - 1].fen
        this.currentDescription = this.moveList[this.moveList.length - 1].description
      }
      this.moveNum = this.moveList.length - 1
    },
    reverseBoard() {
      this.boardColor = this.boardColor === 'white' ? 'black' : 'white';
    },
    reverseRealModeBoard() {
      console.log("reverse")
      this.reverseJump = true
      this.realModeColor = this.realModeColor === 'white' ? 'black' : 'white';
    },
    // 将走法解析成历史记录
    parseMove2History() {
      this.openingMoveHistory = [];
      let black = [];
      let white = [];
      // 先把黑白分开
      for (let i = 0; i < this.currentOpening.data.length; i++) {
        if (i % 2 === 0) {
          white.push({move: this.currentOpening.data[i].move, fen: this.currentOpening.data[i].fen});
        } else {
          black.push({move: this.currentOpening.data[i].move, fen: this.currentOpening.data[i].fen})
        }
      }
      for (let i = 0; i < white.length; i++) {
        let list = {
          index: i + 1,
          white: white[i].move,
          whiteFen: white[i].fen,
          // 白棋肯定会有 黑棋有可能还没开始下
          black: black[i]?.move || '',
          blackFen: black[i]?.fen || null,
        }
        this.openingMoveHistory.push(list);
      }
    },
    // 自动播放
    async autoMove() {
      this.autoLoading = true
      this.jumpToBegin()
      for (let i=1;i<this.moveList.length;i++) {
        await utils.sleep(500)
        this.jumpToNext()
      }
      this.autoLoading = false
    },
    async getOpeningSort() {
      this.openingList = []
      const group = await Database.getOpeningGroup()
      for (const item of group) {
        this.openingList.push({label: item.name, value: item.name})
      }
    },
    // 避免页面打开是空的而获取数据
    async getRandomOpening() {
      const res = await Database.getRandomOpening()
      for (const item of res) {
        item.data = utils.decrypt(item.data)
        item.data = JSON.parse(item.data)
        let moveCount = item.data?.length
        let descriptionCount = 0
        for (const info of item.data) {
          if (info.description) descriptionCount++
        }
        item.moveCount = moveCount
        item.descriptionCount = descriptionCount
      }
      this.openingData = res
    },
    // 实战模式
    async enterRealMode() {
      if (!this.openingData.length) return this.$notify({duration: 1000, title: '通知', message: "请先选择一个开局", type: 'warning'})
      const {fenMap, endGameMap} = chessmate.generateReadModeData(this.openingData)
      this.realModeData = fenMap
      this.realModeEndGameMap = endGameMap
      this.realMode = true
      this.endGameSelectData = []
      for (const fen in endGameMap) {
        this.endGameSelectData.push({label: endGameMap[fen], value: endGameMap[fen]})
      }
    },
    // 切换选边
    sideSelect(color) {
      this.realModeSide = color
      // 自动根据视角切换朝向
      if ( this.realModeColor !== this.realModeSide) {
        this.reverseRealModeBoard()
      }
    },
    async startRealMode() {
      // 先播放一段动画
      for (const item of beginGif) {
        this.realModeFen = item
        await sleep(100)
      }
      this.isBeginRealMode = true
      this.realModeFen = utils.newGame
    },
    // 实战模式获取棋盘
    getRealModeBoardInfo(data) {
      if (!this.isBeginRealMode) {
        console.log("尚未开始实战模式")
        return
      }
      console.log("开始——————————————————data", data)
      const fen = parseFenDropHistory(data.fen)
      const exist = this.realModeData[fen]
      console.log("exist", exist)
      const isWhite = chessmate.isWhite(fen)
      let nextMove = null
      let needMove = false
      // 选了白色，且目前不是白走，则程序自动走子
      if (this.realModeSide === 'white') {
        if (!isWhite) {
          nextMove = this.realModeData[fen]
          needMove = true
        } else {
          console.log("跳过落子")
          return
        }
      } else {
        // 反之 用户选黑色，现在如果轮到白走，则自动走子
        if (isWhite) {
          nextMove = this.realModeData[fen]
          needMove = true
        } else {
          console.log("跳过落子")
          return
        }
      }
      if (!exist) {
        // 而且要先判断是否需要落子
        if (this.realModeEndGameMap[fen])  {
          this.realModeFen = fen  // 必须把这一步的fen也赋值了,才能判断正确
          this.endGameModal = true
          return
        }
        this.$notify({duration: 1000, title: '通知', message: "该落子不是正确的落子，很遗憾，测试失败了。", type: 'error'})
        this.isBeginRealMode = false
        this.realModeFen = utils.emptyGame
        // this.realModeFen = this.realModeLastFen || utils.newGame
        return
      }
      if (nextMove !== null ) {
        const singleMove = randomFromArray(nextMove)
        // this.realModeLastFen = data.fen
        const nextFen = chessmate.move(fen, singleMove)

        this.realModeFen = nextFen
        // 如果是系统自动走子，也需要判断走完了是否到棋局末尾，否则就是bug
        if (this.realModeEndGameMap[nextFen])  {
          this.endGameModal = true
          return
        }
      }
      this.realModeLastFen = this.realModeFen
    },
    // 退出实战模式
    quitRealMode() {
      this.realMode = false
      this.realModeLastFen = utils.newGame
      this.realModeFen = utils.emptyGame
      this.isBeginRealMode = false
    },
    // 重置实战模式
    resetRealMode() {
      this.realModeLastFen = utils.newGame
      this.realModeFen = utils.emptyGame
      this.isBeginRealMode = false

    },
    // 判断最后提交的数据是否正确
    async sendEndGameCheck() {
      const nowName = this.realModeEndGameMap[parseFenDropHistory(this.realModeFen) ]
      if (nowName !== this.endGameSelect) {
        this.$notify({duration: 1000, title: '通知', message: `很遗憾，你选择的开局不正确，正确答案是 ${nowName}`, type: 'error'})
      } else {
        this.$notify({duration: 1000, title: '通知', message: `恭喜，你通过了实战测试`, type: 'success'})
      }
      await sleep(500)
      this.endGameModal = false
      this.isBeginRealMode = false
      this.realModeLastFen = utils.newGame
      this.realModeFen = utils.emptyGame
    },
    importOpening() {
      console.log("this.importFilePath", this.importFilePath)
    },
    exportSimplePgn() {
      console.log("this.openingMoveHistory", this.openingMoveHistory)
      let text = ''
      for (const item of this.openingMoveHistory) {
        text += `${item.index}、${item.white || ''} ${item.black || ''}\n\n`
      }
      clipboard.writeText(text)
      return this.$notify({duration: 1000, title: '通知', message: `简谱已成功复制到剪切板`, type: 'success'})
    },
    async handleImportFile(event) {
      this.importFilePath = event.target.files[0].path
      if (this.importFilePath.indexOf('json') === -1) {
        this.importFilePath = ''
        return this.$notify({duration: 1000, title: '通知', message: `请选择导出的Json文件`, type: 'error'})
      }
      let openingData = fs.readFileSync(this.importFilePath, 'utf-8')
      // 先检测Json文件格式
      try {
        openingData = JSON.parse(openingData)
      } catch {
        return this.$notify({duration: 1000, title: '通知', message: `Json文件格式不正确`, type: 'error'})
      }
      if (openingData.data && openingData.data.length) {
        for (const item of openingData.data) {
          if (!item.name || !item.subName || !item.data || !item.data.length) {
            return this.$notify({duration: 1000, title: '通知', message: `Json文件格式不正确`, type: 'error'})
          }
          await Database.updateOpening(item.name, item.subName, JSON.stringify(item.data))
        }
      } else {
        return this.$notify({duration: 1000, title: '通知', message: `Json文件格式不正确`, type: 'error'})
      }
      return this.$notify({duration: 1000, title: '通知', message: `导入成功`, type: 'success'})
    },
    // 当前屏幕截图
    screenCut() {
      var node = document.getElementById('capture');

      domtoimage
          .toPng(node)
          .then( (dataUrl) => {
            if (!this.exportFilePath)    return this.$notify({duration: 1000, title: '通知', message: `没有配置导出文件目录`, type: 'error'})
            let img = new Image();
            img.src = dataUrl;
            let base64Data = dataUrl.split(',')[1];
            const buffer = Buffer.from(base64Data, 'base64');
            const filePath = path.join(this.exportFilePath, `${this.moveNum}.png`)
            fs.writeFileSync(filePath, buffer, {encoding:'base64'})
            this.$notify({duration: 1000, title: '通知', message: `图片已存放至导出文件目录`, type: 'success'})
          })
          .catch(function (error) {
            console.error('oops, something went wrong!', error);
          });
    },
    async starOpening() {
      console.log("this.star", this.star)
      let text
      if (Number(this.star) === 0) {
        this.star = 1
        text = '设置星标成功'
      }
      else if (Number(this.star) === 1) {
        this.star = 0
        text = '取消星标成功'
      }
      await Database.saveOpeningStar(this.currentOpening.name, this.currentOpening.subName, this.star)
      await this.changeOpening(this.openingName)
      this.$notify({duration: 1000, title: '通知', message: `${text}`, type: 'success'})
    },

  },

  async mounted() {
    this.isDev = location.protocol.indexOf('http') !== -1;
    // 如果是开发模式，默认走老板键
    const isHome = await invoke('isHome', null)
    if (isHome === 'true' || isHome === true) {

    } else {
      this.isBoss = this.isDev
    }
    await this.getSetting()
    await this.getOpeningSort()
    await this.getRandomOpening()
    emitvue.$on('refreshSetting', async () => {
      await this.getSetting()
    })
  },
  components: {
    chessboard,
  },
}
</script>


<style scoped>
.firstLine {
  display: inline-block;
  margin: 5px;
}
.firstLine40 {
  display: inline-block;
  margin: 40px;
}
.pText {
  display: inline-block;
  margin: 5px;
  font-size: 14px;
}
.boss {
  opacity: 0.025;
}
.center {
 text-align: center;
}
.textarea:deep(.el-textarea__inner) {
  outline: none;
  border: none;
  resize: none;
  box-shadow: none;
}
</style>